﻿using System;

namespace UniRx.Operators
{
	// Token: 0x020003F5 RID: 1013
	internal class SampleFrameObservable<T> : OperatorObservableBase<T>
	{
		// Token: 0x060014B6 RID: 5302 RVA: 0x0005D8A7 File Offset: 0x0005BCA7
		public SampleFrameObservable(IObservable<T> source, int frameCount, FrameCountType frameCountType) : base(source.IsRequiredSubscribeOnCurrentThread<T>())
		{
			this.source = source;
			this.frameCount = frameCount;
			this.frameCountType = frameCountType;
		}

		// Token: 0x060014B7 RID: 5303 RVA: 0x0005D8CA File Offset: 0x0005BCCA
		protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
		{
			return new SampleFrameObservable<T>.SampleFrame(this, observer, cancel).Run();
		}

		// Token: 0x04000C04 RID: 3076
		private readonly IObservable<T> source;

		// Token: 0x04000C05 RID: 3077
		private readonly int frameCount;

		// Token: 0x04000C06 RID: 3078
		private readonly FrameCountType frameCountType;

		// Token: 0x020003F6 RID: 1014
		private class SampleFrame : OperatorObserverBase<T, T>
		{
			// Token: 0x060014B8 RID: 5304 RVA: 0x0005D8DC File Offset: 0x0005BCDC
			public SampleFrame(SampleFrameObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
			}

			// Token: 0x060014B9 RID: 5305 RVA: 0x0005D914 File Offset: 0x0005BD14
			public IDisposable Run()
			{
				this.sourceSubscription = new SingleAssignmentDisposable();
				this.sourceSubscription.Disposable = this.parent.source.Subscribe(this);
				IDisposable disposable = Observable.IntervalFrame(this.parent.frameCount, this.parent.frameCountType).Subscribe(new SampleFrameObservable<T>.SampleFrame.SampleFrameTick(this));
				return StableCompositeDisposable.Create(this.sourceSubscription, disposable);
			}

			// Token: 0x060014BA RID: 5306 RVA: 0x0005D97C File Offset: 0x0005BD7C
			private void OnNextTick(long _)
			{
				object obj = this.gate;
				lock (obj)
				{
					if (this.isUpdated)
					{
						T value = this.latestValue;
						this.isUpdated = false;
						this.observer.OnNext(value);
					}
					if (this.isCompleted)
					{
						try
						{
							this.observer.OnCompleted();
						}
						finally
						{
							base.Dispose();
						}
					}
				}
			}

			// Token: 0x060014BB RID: 5307 RVA: 0x0005DA0C File Offset: 0x0005BE0C
			public override void OnNext(T value)
			{
				object obj = this.gate;
				lock (obj)
				{
					this.latestValue = value;
					this.isUpdated = true;
				}
			}

			// Token: 0x060014BC RID: 5308 RVA: 0x0005DA50 File Offset: 0x0005BE50
			public override void OnError(Exception error)
			{
				object obj = this.gate;
				lock (obj)
				{
					try
					{
						this.observer.OnError(error);
					}
					finally
					{
						base.Dispose();
					}
				}
			}

			// Token: 0x060014BD RID: 5309 RVA: 0x0005DAAC File Offset: 0x0005BEAC
			public override void OnCompleted()
			{
				object obj = this.gate;
				lock (obj)
				{
					this.isCompleted = true;
					this.sourceSubscription.Dispose();
				}
			}

			// Token: 0x04000C07 RID: 3079
			private readonly SampleFrameObservable<T> parent;

			// Token: 0x04000C08 RID: 3080
			private readonly object gate = new object();

			// Token: 0x04000C09 RID: 3081
			private T latestValue = default(T);

			// Token: 0x04000C0A RID: 3082
			private bool isUpdated;

			// Token: 0x04000C0B RID: 3083
			private bool isCompleted;

			// Token: 0x04000C0C RID: 3084
			private SingleAssignmentDisposable sourceSubscription;

			// Token: 0x020003F7 RID: 1015
			private class SampleFrameTick : IObserver<long>
			{
				// Token: 0x060014BE RID: 5310 RVA: 0x0005DAF4 File Offset: 0x0005BEF4
				public SampleFrameTick(SampleFrameObservable<T>.SampleFrame parent)
				{
					this.parent = parent;
				}

				// Token: 0x060014BF RID: 5311 RVA: 0x0005DB03 File Offset: 0x0005BF03
				public void OnCompleted()
				{
				}

				// Token: 0x060014C0 RID: 5312 RVA: 0x0005DB05 File Offset: 0x0005BF05
				public void OnError(Exception error)
				{
				}

				// Token: 0x060014C1 RID: 5313 RVA: 0x0005DB08 File Offset: 0x0005BF08
				public void OnNext(long _)
				{
					object gate = this.parent.gate;
					lock (gate)
					{
						if (this.parent.isUpdated)
						{
							T latestValue = this.parent.latestValue;
							this.parent.isUpdated = false;
							this.parent.observer.OnNext(latestValue);
						}
						if (this.parent.isCompleted)
						{
							try
							{
								this.parent.observer.OnCompleted();
							}
							finally
							{
								this.parent.Dispose();
							}
						}
					}
				}

				// Token: 0x04000C0D RID: 3085
				private readonly SampleFrameObservable<T>.SampleFrame parent;
			}
		}
	}
}
